import { _decorator, Button, find, Label, Node, ProgressBar, ScrollView } from 'cc';
import { DataProxy } from '../../../frame/A-LIB/lib.b.data';
import { ScrollList } from '../../../frame/component/scroll.list';
import { BasePopUp } from '../../../frame/component/ui.pop-up';
import Config from '../../manager/config.manager';
import GameDC from '../../manager/data.game.center';
import GameAssets from '../../manager/game.assets';
import type { Popup } from '../page/popup';
const { ccclass, property } = _decorator;

@ccclass('Task')
export class Task extends BasePopUp<typeof Popup, null> {

	@property(ScrollList)
	private scroll_list: ScrollList = null;
	@property(ScrollView)
	private scroll_view: ScrollView = null;

	protected default_return: null;

	protected initAfterOnLoad(){
		this.renderLocalUI();
		this.scroll_list.onRenderItem(this.renderItem.bind(this));
	}

	protected _click_event_: { [name: string]: (this: Task, button: Button) => void; } = {
		close(btn){
			btn.interactable = false;
			BasePopUp.jelly_leave(this.node).then(()=>{
				this.close(null);
				btn.interactable = true;
				GameDC.Trigger.HILIT_DIAMOND = false;
			});
		},
		remove(btn){
			btn.interactable = false;
			this.renderList('remove');
		},
		round(btn){
			btn.interactable = false;
			this.renderList('round');
		},
		reap(btn){
			btn.interactable = false;
			this.reapTask(btn.node.parent.parent);
			btn.interactable = true;
		}
	}

	protected listening(){
		let list = [];

		let [hint_round, hint_remove] = ['round', 'remove'].map(name=>find(name+'/hint', this.node));
		let [lbl_round, lbl_remove] = ['round', 'remove'].map(name=>find(name+'/lbl-hint', this.node).getComponent(Label));

		list.push(
			DataProxy.follow(GameDC.User, 'task_round', ()=>{
				let count = Config.taskRound.filter(el=>!GameDC.checkTask('round', el.round) && el.round < GameDC.User.round).length;
				hint_round.active = count>0;
				lbl_round.string = count>0 ? String(count) : '';
			}, false),
			DataProxy.follow(GameDC.User, 'task_remove', ()=>{
				let count = Config.taskRemove.filter(el=>!GameDC.checkTask('remove', el.count) && el.count <= GameDC.User.remove_count).length;
				hint_remove.active = count>0;
				lbl_remove.string = count>0 ? String(count) : '';
			}, false),
			DataProxy.follow(GameDC.User, 'round', ()=>{
				let count = Config.taskRound.filter(el=>!GameDC.checkTask('round', el.round) && el.round < GameDC.User.round).length;
				hint_round.active = count>0;
				lbl_round.string = count>0 ? String(count) : '';
			}, false),
			DataProxy.follow(GameDC.User, 'remove_count', ()=>{
				let count = Config.taskRemove.filter(el=>!GameDC.checkTask('remove', el.count) && el.count <= GameDC.User.remove_count).length;
				hint_remove.active = count>0;
				lbl_remove.string = count>0 ? String(count) : '';
			}, false)
		);

		let count_round = Config.taskRound.filter(el=>!GameDC.checkTask('round', el.round) && el.round < GameDC.User.round).length;
		hint_round.active = count_round>0;
		lbl_round.string = count_round>0 ? String(count_round) : '';
		let count_remove = Config.taskRemove.filter(el=>!GameDC.checkTask('remove', el.count) && el.count <= GameDC.User.remove_count).length;
		hint_remove.active = count_remove>0;
		lbl_remove.string = count_remove>0 ? String(count_remove) : '';

		return list;
	}

	public onShow(){
		GameDC.Trigger.HILIT_DIAMOND = true;
		this.renderList('round');
		BasePopUp.jelly_enter(this.node);
	}

	private async reapTask(item: Node){

		let data: any;
		if(this.render_type=='round'){
			data = Config.taskRound.find(el=>el.round==Number(item.name));
		}else{
			data = Config.taskRemove.find(el=>el.count==Number(item.name));
		}

		GameDC.recordTask(this.render_type, item.name);
		this.renderItem(item, data, this.scroll_list.NodeCache);

		await this.pop.FruitDiamond(data.diamond);
	}

	private renderLocalUI(){
		(<const>[
			['round', GameAssets.getLangText(52)],
			['remove', GameAssets.getLangText(53)]
		]).forEach(([name, str])=>{
			let btn = this.__btn_map__.get(name);
			['live', 'normal']
			.forEach(lname=>btn.node.getChildByName('lbl-'+lname).getComponent(Label).string = str);
		});

		this.scroll_view.content.children.forEach(node=>{
			mtec.cc.skinPeeler(find('button/underway', node), GameAssets.getLangTexture(2), {width: true});
		});
	}

	private render_type: 'round' | 'remove' = 'round';
	private renderList(type: 'round' | 'remove'){
		this.render_type = type;
		if(type=='round'){
			this.scroll_list.setDataList(Config.taskRound.filter(el=>!GameDC.checkTask('round', el.round)), 'round');
		}else{
			this.scroll_list.setDataList(Config.taskRemove.filter(el=>!GameDC.checkTask('remove', el.count)), 'count');
		}

		this.scroll_view.scrollToTop(0.05);

		['round', 'remove'].forEach(name=>{
			let btn = this.__btn_map__.get(name);
			btn.interactable = name!=type;

			btn.node.getChildByName('bg-live').active = !btn.interactable;
			btn.node.getChildByName('bg-normal').active = btn.interactable;

			btn.node.getChildByName('lbl-live').active = !btn.interactable;
			btn.node.getChildByName('lbl-normal').active = btn.interactable;
		});
	}

	private renderItem( node: Node, data: any, node_cache: Map<Node, __TaskNodeCache__> ){
		let cache = node_cache.get(node);
		if(!cache){
			cache = this.createCache(node);
			node_cache.set(node, cache);
		}

		if(this.render_type=='round'){
			cache.lbl_desc_remove.node.active = false;
		}else{
			[
				cache.mark_hard,
				cache.mark_simple,
				cache.lbl_mark.node,
				cache.lbl_desc_round.node,
			].forEach(n=>n.active = false);
		}

		if(this.render_type=='round'){
			this.renderRoundItem(cache, data);
		}else{
			this.renderRemoveItem(cache, data);
		}
	};

	private renderRoundItem(cache: __TaskNodeCache__, data: typeof Config.taskRound[number]){
		cache.mark_hard.active = data.isHard;
		cache.mark_simple.active = !data.isHard;
		cache.lbl_mark.node.active = true;
		cache.lbl_mark.string = GameAssets.getLangText(data.isHard ? 55 : 54);
		cache.lbl_desc_round.string = GameAssets.getLangText(56, data.round);

		cache.lbl_desc_round.node.active = true;
		cache.lbl_diamond.string = String(data.diamond);

		let round = Math.min(GameDC.User.round-1, data.round);
		let progress = Math.max(0, Math.min(1, round/data.round));

		cache.bar.progress = progress;
		cache.lbl_progress.string = `${round} / ${data.round}`;

		let done = GameDC.checkTask('round', data.round);
		let full = progress>=1;

		cache.done.active = done;
		cache.underway.active = !done && !full;
		cache.reap.active = !done && full;
		cache.lbl_button.node.active = !cache.underway.active;
		if(cache.lbl_button.node.active){
			cache.lbl_button.string = GameAssets.getLangText(done ? 58 : 57);
		}
	}

	private renderRemoveItem(cache: __TaskNodeCache__, data: typeof Config.taskRemove[number]){
		cache.lbl_desc_remove.node.active = true;
		cache.lbl_desc_remove.string = GameAssets.getLangText(59, data.count);
		cache.lbl_diamond.string = String(data.diamond);

		let count = Math.min(GameDC.User.remove_count, data.count);
		let progress = Math.max(0, Math.min(1, count/data.count));

		cache.bar.progress = progress;
		cache.lbl_progress.string = `${count} / ${data.count}`;

		let done = GameDC.checkTask('remove', data.count);
		let full = progress>=1;

		cache.done.active = done;
		cache.underway.active = !done && !full;
		cache.reap.active = !done && full;
		cache.lbl_button.node.active = !cache.underway.active;
		if(cache.lbl_button.node.active){
			cache.lbl_button.string = GameAssets.getLangText(done ? 58 : 57);
		}
	}

	private createCache(item_node: Node){
		let button = item_node.getChildByName('button');
		let cache: __TaskNodeCache__ = {
			bar: item_node.getChildByName('progress').getComponent(ProgressBar),
			mark_hard: item_node.getChildByName('mark-hard'),
			mark_simple: item_node.getChildByName('mark-simple'),
			done: button.getChildByName('done'),
			underway: button.getChildByName('underway'),
			reap: button.getChildByName('reap'),
			lbl_button: item_node.getChildByName('lbl-button').getComponent(Label),
			lbl_diamond: item_node.getChildByName('lbl-diamond').getComponent(Label),
			lbl_progress: item_node.getChildByName('lbl-progress').getComponent(Label),
			lbl_desc_remove: item_node.getChildByName('lbl-desc-remove').getComponent(Label),
			lbl_desc_round: item_node.getChildByName('lbl-desc-round').getComponent(Label),
			lbl_mark: item_node.getChildByName('lbl-mark').getComponent(Label),
		};
		return cache;
	}
}

type __TaskNodeCache__ = {
	mark_hard: Node;
	mark_simple: Node;
	done: Node;
	underway: Node;
	reap: Node;
	bar: ProgressBar;
	lbl_mark: Label;
	lbl_progress: Label;
	lbl_button: Label;
	lbl_diamond: Label;
	lbl_desc_round: Label;
	lbl_desc_remove: Label;
}

